#include <iostream>
#include <vector>
#include <set>
#include <unordered_map>
#include <string>
#include <algorithm>

using namespace std;

vector<vector<int>> threeSum(vector<int> &nums)
{
    unordered_map<int, int> nums_map;
    set<vector<int>> result_set;

    for (const auto &it : nums)
    {
        nums_map[it]++;
    }    
    
    for (auto it = nums_map.begin(); it != nums_map.end(); it++)
    {
        const int a = it->first;
        for (auto jt = it; jt != nums_map.end(); jt++)
        {
            const int b = jt->first;
            const int c = -(a + b);
            if (nums_map.find(c) == nums_map.end())
            {
                continue;
            }

            const int count_a = nums_map[a];
            const int count_b = nums_map[b];
            const int count_c = nums_map[c];

            if (a == b && b == c)
            {
                if (count_a < 3)
                {
                    continue;
                }
            }
            else if (a == c)
            {
                if (count_a < 2)
                {
                    continue;
                }
            }
            else if(a == b)
            {
                 if (count_a < 2)
                 {
                    continue;
                 }
                 
            }
            else if (b == c)
            {
                if (count_b < 2)
                {
                    continue;
                }
            }
            
            vector<int> tmp_result = {a, b, c};
            std::sort(tmp_result.begin(), tmp_result.end());
            result_set.insert(tmp_result);
        }
    }
    
    return (vector<vector<int>>(result_set.begin(), result_set.end()));
}

void TestCase(vector<int> nums)
{
    const auto&result= threeSum(nums);

    if (result.empty())
    {
        std::cout<<"[]"<<std::endl;
    }
    else
    {
        for (const auto &vec : result)
        {
            std::cout << "[" << vec[0] << ", " << vec[1] << ", " << vec[2] << "]" << std::endl;
        }
    }
}



int main()
{
    std::cout << "============================TestCase1============================" << std::endl;
    vector<int> nums_1 = {-1 ,0,1,2,-1,-4};
    TestCase(nums_1);
    std::cout << "============================TestCase2============================" << std::endl;  
    vector<int> nums_2 = {0,1,1};
    TestCase(nums_2);
    std::cout << "============================TestCase3============================" << std::endl;  
    vector<int> nums_3 = {0,0,0};
    TestCase(nums_3);
    return 0;
}
